﻿using System.Collections.Generic;
using GoGameClient.script.global;
using Godot;

namespace GoGameClient.script.resources;

public class MapInfo
{
    public string Flag { get; set; }
    public int Height { get; set; }
    public int Width { get; set; }
    public int Col { get; set; }
    public int Row { get; set; }
    public int MapColNum { get; set; }
    public int MapRowNum { get; set; }
    public int MapNum { get; set; }
}

public class MapResources : IResources
{
    private string Map { get; set; } = ResourcesControl.RootPath + "map";

    private readonly List<Vector2I> _resourceMapList;
    private int Id { get; }

    public void ApplyTileSource(Vector2I position)
    {
        _resourceMapList.Add(position);
        ResourceLoader.LoadThreadedRequest($"{GetPath()}/{Id}/{position.X}-{position.Y}.png");
    }

    public List<TileInfo> TileSetAtlasSources()
    {
        if (_resourceMapList.Count <= 0)
        {
            return null;
        }

        var tileSetAtlasSources = new List<TileInfo>();
        for (var i = _resourceMapList.Count - 1; i >= 0; i--)
        {
            var tileSetAtlasSource = TryGetTile(_resourceMapList[i]);
            if (tileSetAtlasSource == null) continue;
            var tileInfo = new TileInfo()
            {
                TileSetAtlasSource = tileSetAtlasSource,
                Offset = _resourceMapList[i]
            };
            tileSetAtlasSources.Add(tileInfo);
            _resourceMapList.Remove(_resourceMapList[i]);
        }

        return tileSetAtlasSources;
    }


    private TileSetAtlasSource TryGetTile(Vector2I vector)
    {
        var block = TryGetBlock(vector);
        return block == null ? null : GetTileSetAtlasSource(block);
    }

    private TileSetAtlasSource GetTileSetAtlasSource(Texture2D block)
    {
        var mapInfo = ResourcesControl.Instance().GetMapInfo(Id);
        var tileSetAtlasSource = new TileSetAtlasSource()
        {
            Texture = block,
            TextureRegionSize = new Vector2I(mapInfo.Col, mapInfo.Row)
        };
        tileSetAtlasSource.CreateTile(new Vector2I(0, 0));
        return tileSetAtlasSource;
    }


    private Texture2D TryGetBlock(Vector2I vector)
    {
        var path = $"{GetPath()}/{Id}/{vector.X}-{vector.Y}.png";
        if (ResourceLoader.LoadThreadedGetStatus(path) != ResourceLoader.ThreadLoadStatus.Loaded) return null;

        return (Texture2D)ResourceLoader.LoadThreadedGet(path);
    }


    public MapResources(int id)
    {
        Id = id;
        _resourceMapList = new List<Vector2I>();
    }


    public string GetPath()
    {
        return Map;
    }

    public void SetPath(string path)
    {
        Map = ResourcesControl.RootPath + path;
    }
}

public class TileInfo
{
    public TileSetAtlasSource TileSetAtlasSource { get; init; }
    public Vector2I Offset { get; init; }
}